package functional_programming;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @version: 1.0
 * @Description: TODO
 * @author: zZmH
 * @date: 2020/10/03 17:32
 */


public class Shop {
    private String name;
    public Shop(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Shop shop = new Shop("BestShop");
        long time = System.nanoTime();
        Future<Double> futureProductPrice = shop.getPriceAsync("my favourite product");
        System.out.println("async: " + (System.nanoTime() - time)/1000000);
        shop.dosthElse();
        Double aDouble = null;
        try {
            aDouble = futureProductPrice.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(aDouble);
        System.out.println("async received: " + (System.nanoTime() - time)/1000000);

        List<Shop> shops = Arrays.asList(new Shop("BestPrice"),
                new Shop("LetsSaveBig"),
                new Shop("MyFavoriteShop"),
                new Shop("BuyItAll"));

        shops.parallelStream()
                .map(s -> String.format("%s price",
                        s.getName()))
                .forEach(System.out::println);

        List<CompletableFuture<String>> collect = shops.parallelStream()
                .map(s -> CompletableFuture.supplyAsync(() -> String.format("%s price",
                        s.getName())))
                .collect(toList());

        collect.stream()
                .map(CompletableFuture::join)
                .forEach(System.out::println);
    }
    public Future<Double> getPriceAsync2(String product) {

        return CompletableFuture.supplyAsync(() -> calculatePrice(product));

    }


    public Future<Double> getPriceAsync(String product) {
        CompletableFuture<Double> future = new CompletableFuture<>();
        new Thread(() -> {
            try {

                future.complete(calculatePrice(product));
            } catch (Exception e) {
                future.completeExceptionally(e);
            }
        }).start();

        return future;
    }

    //同步方法
    public double getPrice(String product) {
       return calculatePrice(product);
    }

    private double calculatePrice(String product) {
        try {
            Thread.sleep(2000);

        }
        finally {
            return new Random().nextDouble() * product.charAt(0) + product.charAt(1);
        }



    }

    private void dosthElse(){
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
        System.out.println("cnm");
    }


}
